<{extend name="Public:public" /}>

<{block name="title"}>Vue 实例<{/block}>

<{block name="content"}> 
<style type="text/css">
#vantranslate>span {
	background: #ddd;
	padding: 0 10px;
	white-space: nowrap;
}
</style>

<div class="content guide with-sidebar instance-guide">
    <h1>Vue 实例</h1>
  
    <h2 id="创建一个-Vue-实例"><a href="#创建一个-Vue-实例" class="headerlink" title="创建一个 Vue 实例" data-scroll="">创建一个 Vue 实例</a></h2><p>每个 Vue 应用都是通过用 <code>Vue</code> 函数创建一个新的 <strong>Vue 实例</strong>开始的：</p>
<figure class="highlight js"><table><tbody><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> Vue({</span><br><span class="line">  <span class="comment">// 选项</span></span><br><span class="line">})</span><br></pre></td></tr></tbody></table></figure>
<p>虽然没有完全遵循 <a href="https://zh.wikipedia.org/wiki/MVVM" target="_blank" rel="noopener">MVVM 模型</a>，但是 Vue 的设计也受到了它的启发。因此在文档中经常会使用 <code>vm</code> (ViewModel 的缩写) 这个变量名表示 Vue 实例。</p>
<p>当创建一个 Vue 实例时，你可以传入一个<strong>选项对象</strong>。这篇教程主要描述的就是如何使用这些选项来创建你想要的行为。作为参考，你也可以在 <a href="../api/#选项-数据">API 文档</a> 中浏览完整的选项列表。</p>
<p>一个 Vue 应用由一个通过 <code>new Vue</code> 创建的<strong>根 Vue 实例</strong>，以及可选的嵌套的、可复用的组件树组成。举个例子，一个 todo 应用的组件树可以是这样的：</p>
<figure class="highlight plain"><table><tbody><tr><td class="code"><pre><span class="line">根实例</span><br><span class="line">└─ TodoList</span><br><span class="line">   ├─ TodoItem</span><br><span class="line">   │  ├─ DeleteTodoButton</span><br><span class="line">   │  └─ EditTodoButton</span><br><span class="line">   └─ TodoListFooter</span><br><span class="line">      ├─ ClearTodosButton</span><br><span class="line">      └─ TodoListStatistics</span><br></pre></td></tr></tbody></table></figure>
<p>我们会在稍后的<a href="components.html">组件系统</a>章节具体展开。不过现在，你只需要明白所有的 Vue 组件都是 Vue 实例，并且接受相同的选项对象 (一些根实例特有的选项除外)。</p>
<h2 id="数据与方法"><a href="#数据与方法" class="headerlink" title="数据与方法" data-scroll="">数据与方法</a></h2><p>当一个 Vue 实例被创建时，它向 Vue 的<strong>响应式系统</strong>中加入了其 <code>data</code> 对象中能找到的所有的属性。当这些属性的值发生改变时，视图将会产生“响应”，即匹配更新为新的值。</p>
<figure class="highlight js"><table><tbody><tr><td class="code"><pre><span class="line"><span class="comment">// 我们的数据对象</span></span><br><span class="line"><span class="keyword">var</span> data = { <span class="attr">a</span>: <span class="number">1</span> }</span><br><span class="line"></span><br><span class="line"><span class="comment">// 该对象被加入到一个 Vue 实例中</span></span><br><span class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> Vue({</span><br><span class="line">  data: data</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获得这个实例上的属性</span></span><br><span class="line"><span class="comment">// 返回源数据中对应的字段</span></span><br><span class="line">vm.a == data.a <span class="comment">// =&gt; true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 设置属性也会影响到原始数据</span></span><br><span class="line">vm.a = <span class="number">2</span></span><br><span class="line">data.a <span class="comment">// =&gt; 2</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// ……反之亦然</span></span><br><span class="line">data.a = <span class="number">3</span></span><br><span class="line">vm.a <span class="comment">// =&gt; 3</span></span><br></pre></td></tr></tbody></table></figure>
<p>当这些数据改变时，视图会进行重渲染。值得注意的是只有当实例被创建时 <code>data</code> 中存在的属性才是<strong>响应式</strong>的。也就是说如果你添加一个新的属性，比如：</p>
<figure class="highlight js"><table><tbody><tr><td class="code"><pre><span class="line">vm.b = <span class="string">'hi'</span></span><br></pre></td></tr></tbody></table></figure>
<p>那么对 <code>b</code> 的改动将不会触发任何视图的更新。如果你知道你会在晚些时候需要一个属性，但是一开始它为空或不存在，那么你仅需要设置一些初始值。比如：</p>
<figure class="highlight js"><table><tbody><tr><td class="code"><pre><span class="line">data: {</span><br><span class="line">  newTodoText: <span class="string">''</span>,</span><br><span class="line">  visitCount: <span class="number">0</span>,</span><br><span class="line">  hideCompletedTodos: <span class="literal">false</span>,</span><br><span class="line">  todos: [],</span><br><span class="line">  error: <span class="literal">null</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure>
<p>这里唯一的例外是使用 <code>Object.freeze()</code>，这会阻止修改现有的属性，也意味着响应系统无法再<em>追踪</em>变化。</p>
<figure class="highlight js"><table><tbody><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = {</span><br><span class="line">  foo: <span class="string">'bar'</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="built_in">Object</span>.freeze(obj)</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> Vue({</span><br><span class="line">  el: <span class="string">'#app'</span>,</span><br><span class="line">  data: obj</span><br><span class="line">})</span><br></pre></td></tr></tbody></table></figure>
<figure class="highlight html"><table><tbody><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"app"</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">p</span>&gt;</span>{{ foo }}<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!-- 这里的 `foo` 不会更新！ --&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">button</span> <span class="attr">v-on:click</span>=<span class="string">"foo = 'baz'"</span>&gt;</span>Change it<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></tbody></table></figure>
<p>除了数据属性，Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀 <code>$</code>，以便与用户定义的属性区分开来。例如：</p>
<figure class="highlight js"><table><tbody><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> data = { <span class="attr">a</span>: <span class="number">1</span> }</span><br><span class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> Vue({</span><br><span class="line">  el: <span class="string">'#example'</span>,</span><br><span class="line">  data: data</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line">vm.$data === data <span class="comment">// =&gt; true</span></span><br><span class="line">vm.$el === <span class="built_in">document</span>.getElementById(<span class="string">'example'</span>) <span class="comment">// =&gt; true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// $watch 是一个实例方法</span></span><br><span class="line">vm.$watch(<span class="string">'a'</span>, <span class="function"><span class="keyword">function</span> (<span class="params">newValue, oldValue</span>) </span>{</span><br><span class="line">  <span class="comment">// 这个回调将在 `vm.a` 改变后调用</span></span><br><span class="line">})</span><br></pre></td></tr></tbody></table></figure>
<p>以后你可以在 <a href="../api/#实例属性">API 参考</a>中查阅到完整的实例属性和方法的列表。</p>
<h2 id="实例生命周期钩子"><a href="#实例生命周期钩子" class="headerlink" title="实例生命周期钩子" data-scroll="">实例生命周期钩子</a></h2><p>每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如，需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做<strong>生命周期钩子</strong>的函数，这给了用户在不同阶段添加自己的代码的机会。</p>
<p>比如 <a href="../api/#created"><code>created</code></a> 钩子可以用来在一个实例被创建之后执行代码：</p>
<figure class="highlight js"><table><tbody><tr><td class="code"><pre><span class="line"><span class="keyword">new</span> Vue({</span><br><span class="line">  data: {</span><br><span class="line">    a: <span class="number">1</span></span><br><span class="line">  },</span><br><span class="line">  created: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line">    <span class="comment">// `this` 指向 vm 实例</span></span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'a is: '</span> + <span class="keyword">this</span>.a)</span><br><span class="line">  }</span><br><span class="line">})</span><br><span class="line"><span class="comment">// =&gt; "a is: 1"</span></span><br></pre></td></tr></tbody></table></figure>
<p>也有一些其它的钩子，在实例生命周期的不同阶段被调用，如 <a href="../api/#mounted"><code>mounted</code></a>、<a href="../api/#updated"><code>updated</code></a> 和 <a href="../api/#destroyed"><code>destroyed</code></a>。生命周期钩子的 <code>this</code> 上下文指向调用它的 Vue 实例。</p>
<p class="tip">不要在选项属性或回调上使用<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions" target="_blank" rel="noopener">箭头函数</a>，比如 <code>created: () =&gt; console.log(this.a)</code> 或 <code>vm.$watch('a', newValue =&gt; this.myMethod())</code>。因为箭头函数是和父级上下文绑定在一起的，<code>this</code> 不会是如你所预期的 Vue 实例，经常导致 <code>Uncaught TypeError: Cannot read property of undefined</code> 或 <code>Uncaught TypeError: this.myMethod is not a function</code> 之类的错误。</p>

<h2 id="生命周期图示"> 
	<a href="#生命周期图示" class="headerlink" title="生命周期图示" data-scroll="">生命周期图示</a> 
</h2> 
<p>下图展示了实例的生命周期。你不需要立马弄明白所有的东西，不过随着你的不断学习和使用，它的参考价值会越来越高。</p>
<p id="vantranslate"> 
<span>lifecycle: 生命周期</span> 
<span>init injections & reactivity: 通过依赖注入导入依赖项</span> 
<span>render function: 渲染函数</span> 
<span>create vm.$el and replace "el" with it: 编译，并替换了被绑定元素</span> 
<span>mounted: 挂载</span> 
<span>Virtual DOM re-render and patch: 虚拟DOM 重新渲染和修补</span> 
<span>Teardown: 拆卸</span> 
</p>
<p style="width:700px"><img src="/images/lifecycle.png" alt="Vue 实例生命周期"></p>

  
  
    <div class="guide-links">
      
      
        <span>← <a href="/v2/guide/index.html">介绍</a></span>
      
      
      
        <span style="float: right;"><a href="/v2/guide/syntax.html">模板语法</a> →</span>
      
    </div>
  
  <div class="footer">
<div class="bsa-cpc"></div>
<script>
  (function(){
    if(typeof _bsa !== 'undefined' && _bsa) {
    _bsa.init('default', 'CKYD62QM', 'placement:vuejsorg', {
      target: '.bsa-cpc',
      align: 'horizontal',
      disable_css: 'true'
    });
      }
  })();
</script>

    发现错误？想参与编辑？
    <a href="https://github.com/vuejs/cn.vuejs.org/blob/master/src/v2/guide/instance.md" target="_blank">
      在 GitHub 上编辑此页！
    </a>
  </div>
</div>


<{/block}>
